#ifndef __ACCEPTOR_H__
#define __ACCEPTOR_H__

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/serialization/vector.hpp>
#include <iostream>
#include <vector>
#include "Connection.hpp"

class CAcceptor
{
public:
	CAcceptor( boost::asio::io_service& io_service, unsigned short port );
	~CAcceptor( void );

public:
	void Accept( void );

	template< typename T > void Read( T& t, ConnectionPtr conn )
	{
		conn->async_read( t, boost::bind(&CAcceptor::OnRead, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred, conn) );
	}

	template< typename T > void Write( T& t, ConnectionPtr conn )
	{
		conn->async_write( t, boost::bind(&CAcceptor::OnWrite, this, boost::asio::placeholders::error, conn) );
	}

protected:
	// Handle completion of a connect operation.
	void OnAccept( const boost::system::error_code& e, ConnectionPtr conn );
	
	// Handle completion of a read operation.
	void OnRead( const boost::system::error_code& e, size_t bytes_transferred, ConnectionPtr conn );

	// Handle completion of a write operation.
	void OnWrite( const boost::system::error_code& e, ConnectionPtr conn );

private:
	virtual void OnAcceptFailed( const boost::system::error_code& e, ConnectionPtr conn )							= 0;
	virtual void OnReadFailed( const boost::system::error_code& e, size_t bytes_transferred, ConnectionPtr conn )	= 0;
	virtual void OnWriteFailed( const boost::system::error_code& e, ConnectionPtr conn )							= 0;
	virtual void OnAcceptSuccessed( ConnectionPtr conn )															= 0;
	virtual void OnReadSuccessed( size_t bytes_transferred, ConnectionPtr conn )									= 0;
	virtual void OnWriteSuccessed( ConnectionPtr conn )																= 0;

protected:
	boost::asio::ip::tcp::acceptor m_Acceptor;
};

#endif	// __ACCEPTOR_H__